package com.hyfrogx.modules.sys.controller;

import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.spring.annotation.ResponseJSONP;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.hyfrogx.common.annotation.SysLog;
import com.hyfrogx.common.base.QueryForm;
import com.hyfrogx.common.utils.R;
import com.hyfrogx.common.validator.group.AddGroup;
import com.hyfrogx.common.validator.group.UpdateGroup;
import com.hyfrogx.modules.sys.entity.SysFileEntity;
import com.hyfrogx.modules.sys.form.file.FileSaveForm;
import com.hyfrogx.modules.sys.form.file.FileUpdateForm;
import com.hyfrogx.modules.sys.form.file.FileVo;
import com.hyfrogx.modules.sys.service.SysFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 文件 前端控制器
 * </p>
 *
 * @author wanglei
 * @date 2019-07-23 18:36:07
 */
@RestController
@RequestMapping("/sys/file")
@ApiIgnore
@Api(value = "文件controller", tags = {"sys--文件"})
public class SysFileController extends AbstractController {

	@Autowired
	private SysFileService fileService;

	//	@ApiOperation("文件信息")
	@PostMapping("/info/{id}")
	@RequiresPermissions("sys:file:info")
	public R info(@PathVariable("id") Long id) {
		FileVo vo = fileService.queryVoById(id, FileVo.class);
		return R.ok().put("data", vo);
	}

	//	@ApiOperation("文件列表")
	@PostMapping("/select")
	@RequiresPermissions("sys:file:select")
	public R select(@RequestBody QueryForm<SysFileEntity> form) {
		List<FileVo> list = fileService.queryVoList(
				fileService.getSelectWrapper(form, true)
				, FileVo.class
		);
		return R.ok().put("list", list);
	}


	//	@ApiOperation("文件列表")
	@PostMapping("/list")
	@RequiresPermissions("sys:file:list")
	public R list(@RequestBody QueryForm<SysFileEntity> form) {
		IPage page = fileService.queryVoPage(
				form.getIPage(),
				fileService.getSelectWrapper(form, false)
				, FileVo.class
		);
		return R.ok().put("page", page);
	}

	//	@ApiOperation("文件新建")
	@SysLog("保存文件")
	@PostMapping("/save")
	@RequiresPermissions("sys:file:save")
	public R save(@RequestBody @Validated(AddGroup.class) FileSaveForm form) {
		if (ObjectUtil.isNotNull(fileService.saveForm(getUserId(), form))) {
			return R.ok();
		}
		return R.error("保存文件失败");
	}

	//	@ApiOperation("文件更新")
	@SysLog("更新文件")
	@PostMapping("/update")
	@RequiresPermissions("sys:file:update")
	public R update(@RequestBody @Validated(UpdateGroup.class) FileUpdateForm form) {
		if (ObjectUtil.isNotNull(fileService.updateForm(getUserId(), form))) {
			return R.ok();
		}
		return R.error("修改文件失败");
	}

	//	@ApiOperation("文件启用")
	@SysLog("启用文件")
	@PostMapping("/enable")
	@RequiresPermissions("sys:file:enable")
	public R enable(@RequestBody List<Long> ids) {
		if (fileService.enableByIdList(getUserId(), ids)) {
			return R.ok();
		}
		return R.error("启用文件失败");
	}

	@ApiOperation("文件禁用")
	@SysLog("禁用文件")
	@PostMapping("/disable")
	@RequiresPermissions("sys:file:disable")
	public R disable(@RequestBody List<Long> ids) {
		if (fileService.disableByIdList(getUserId(), ids)) {
			return R.ok();
		}
		return R.error("禁用文件失败");
	}


	//	@ApiOperation("文件删除")
	@SysLog("删除文件")
	@PostMapping("/delete")
	@RequiresPermissions("sys:file:delete")
	public R delete(@RequestBody List<Long> ids) {
		if (fileService.deleteByIdList(getUserId(), ids)) {
			return R.ok();
		}
		return R.error("删除文件失败");
	}

	@ApiOperation("文件上传")
	@SysLog("上传文件")
	@PostMapping("/upload")
	@RequiresPermissions("sys:file:upload")
	public R update(MultipartFile file) {
		String fileId = fileService.uploadForm(file);
		if (StrUtil.isNotBlank(fileId)) {
			return R.ok().put("data", new JSONObject().put("fileId", fileId));
		}
		return R.error("文件上传失败");
	}

	/**
	 * ueditor上传配置
	 *
	 * @return
	 */
	@ResponseJSONP
	@GetMapping(value = "/ueditor")
	public Object ueditorConfig(HttpServletRequest request, @RequestParam String action) {
		Map<String, String> params = ServletUtil.getParamMap(request);
		if (StrUtil.equals(action, "config")) {
			String fileName = null;
			if (params.containsKey("file")) {
				fileName = MapUtil.getStr(params, "file");
			}
			if (StrUtil.isBlank(fileName)) {
				fileName = "config.json";
			}
			String json = ResourceUtil.readStr("classpath:/libs/ueditor/" + fileName, Charset.forName("UTF-8"));
			return JSON.parseObject(json);
		}
		return null;
	}

	@PostMapping(value = "/ueditor")
	public Object ueditorUpload(MultipartFile file) {
		String fileId = fileService.uploadForm(file);
		if (StrUtil.isNotBlank(fileId)) {
			return R.ok().put("data", new JSONObject().put("fileId", fileId));
		}
		return R.error("文件上传失败");
	}

	@ApiOperation("文件下载")
	@SysLog("下载文件")
	@GetMapping("/download/{fileId}")
	@RequiresPermissions("sys:file:download")
	public void download(@PathVariable String fileId, HttpServletResponse response) {
		fileService.downloadByFileId(response, fileId);
	}
}

